﻿namespace DangerousRiver
{
    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    class Player
    {
        public string name;
        public int score;
        public Player(string name, int score)
        {
            this.name = name;
            this.score = score;
        }
    }
    class ScoreEngine
    {
        //assuming that the scores are going to be kept in highscores.txt
        //the file keeps the 10 best players
        //and also assuming that the scores are kept in the form 
        //name-score
        const string highscoresFileName = "../../highscores.txt";
        /// <summary>
        /// The method is supposed to load the highscores from the file and return an array of Players with the information
        /// </summary>
        /// <returns>An array of Players</returns>
        public static List<Player> LoadHighscores()
        {
            //in `players` the 10 highest scorers are kept 
            List<Player> players = new List<Player>();
            //reader for getting info out of the highscore file
            try
            {
                StreamReader reader = new StreamReader(highscoresFileName);
                using (reader)
                {
                    string line = "";
                    //Getting the 10 lines of highscores
                    for (int currentLine = 0; currentLine < 10; currentLine++)
                    {
                        line = reader.ReadLine();
                        Player temporaryObject = new Player(line.Split('-')[0], int.Parse(line.Split('-')[1]));
                        players.Add(temporaryObject);
                    }
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("The file which contains highscores can't be found!");
            }
            catch (Exception)
            {
                Console.WriteLine("The file which contains highscores can't be accessed!");
            }

            return players;
        }

        /// <summary>
        /// Saving the score to a file. Basically we get the list of highscorers, 
        /// we check if the current player is a highscorer and if he is, we place him ontop of the last highscorer
        /// we sort the new list and save it to the file
        /// </summary>
        /// <param name="playerName">The name of the player</param>
        /// <param name="score">The score he/she has achieved</param>
        public static void SaveScore(string playerName, int score)
        {
            List<Player> highscorers = LoadHighscores(); //the 10 highscorers
            try
            {
                if (highscorers.Last().score > score) //if the current player isn't a highscorer
                {
                    Console.WriteLine("Sorry, {0}! You didn't manage to get an eligible high score!", playerName);
                    return;
                }
                //removing the last element
                highscorers.RemoveAt(highscorers.IndexOf(highscorers.Last()));
                //placing the current player in the list
                highscorers.Add(new Player(playerName, score));
                //Sorting the list
                SortListPlayers(highscorers);
            }
            catch(InvalidOperationException)
            {
                Console.WriteLine("Your score can't be saved.");
            }
            catch (Exception)
            {
                Console.WriteLine("Your score can't be saved.");
            }
            
            try
            {
                //write the result in the file
                StreamWriter writer = new StreamWriter(highscoresFileName);
                using (writer)
                {
                    foreach (Player player in highscorers)
                    {
                        //in the pattern 
                        //name-score
                        writer.WriteLine("{0}-{1}", player.name, player.score);
                    }
                }
            }
            catch (ArgumentException)
            {
                Console.WriteLine("The file which contains highscores can't be found!");
            }
            catch (Exception)
            {
                Console.WriteLine("The file which contains highscores can't be found!");
            } 
        }

        /// <summary>
        /// A method to sort a list of players using selection sort
        /// </summary>
        /// <param name="playersList">The unsorted list</param>
        /// <returns>The sorted list</returns>
        public static List<Player> SortListPlayers(List<Player> playersList)
        {
            int maxIndex = 0;
            Player maxPlayer = new Player("", 0);
            for (int i = 0; i < playersList.Count - 1; i++)
            {
                maxPlayer = playersList[i];
                maxIndex = i;
                for (int j = i + 1; j < playersList.Count; j++)
                {
                    if (maxPlayer.score < playersList[j].score)
                    {
                        maxPlayer = playersList[j];
                        maxIndex = j;
                    }
                }
                if (maxIndex != i)
                {
                    Player tempPlayer = playersList[i];
                    playersList[i] = playersList[maxIndex];
                    playersList[maxIndex] = tempPlayer;
                }
            }
            return playersList;
        }

        /// <summary>
        /// Read from a text file, players' names and scores.
        /// </summary>
        public static void PrintTopScores()
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("{0,36} \n", "Game Champions!");
            Console.WriteLine("{0,20} {1,21}", "Name", "Score");
            Console.WriteLine();
            List<Player> playersToPrint = LoadHighscores();

            foreach (var player in playersToPrint)
            {
                Console.ForegroundColor = ConsoleColor.Magenta;
                Console.WriteLine("{0,20} {1,21}", player.name, player.score);
            }
            Console.ResetColor();
        }
    }
}